package com.kelp.codetoolkit.actions

import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.LangDataKeys
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiField
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.javadoc.PsiDocComment
import com.kelp.codetoolkit.enums.MySQLDataTypeDefaultValueEnum
import com.kelp.codetoolkit.ui.form.GeneratorDDLDialog
import com.kelp.codetoolkit.utils.NameHandleUtil

/**
 * @author: liuyuebai
 * @date: 2024/10/21 20:13
 * @description:
 */
class ProjectLeftViewClassGeneratorTableAction:AnAction() {
    override fun actionPerformed(e: AnActionEvent) {
        val project = e.project?:return
        val psiFile = e.getData(LangDataKeys.PSI_FILE)?: return
        if (psiFile is PsiJavaFile) {
            val psiClass = psiFile.classes[0]
            val fields = psiClass.fields
            val tableName = getTableName(psiFile)
            var docComment: PsiDocComment? = null
            if (psiClass.docComment != null){
                docComment = psiClass.docComment
            }
            generatorDDL(project, tableName, fields,docComment)
        }
    }

    private fun generatorDDL(project: Project, tableName:String, psiFields: Array<PsiField>,psiDocComment: PsiDocComment?) {
        val tableStatement = StringBuilder()
        tableStatement.append("CREATE TABLE ").append(tableName).append("(")
        val osName = System.getProperty("os.name")
        if (osName.contains("Windows")) {
            tableStatement.append("\r\n")
        }
        if (osName.contains("Linux")) {
            tableStatement.append("\n")
        }
        for (field in psiFields) {
            if ("serialVersionUID" == field.name) {
                continue
            }
            val canonicalText = field.type.canonicalText
            val defaultValue = MySQLDataTypeDefaultValueEnum.getTypeDefaultValue(canonicalText)
            val fieldName = NameHandleUtil.camelCaseToUnderscore(field.name)
            var docComment = field.docComment?.text
            docComment = docComment?.replace(Regex("\n|\r\n"), "")
            docComment = docComment?.replace(Regex("/"), "")
            docComment = docComment?.replace(Regex("\\*"), "")
            docComment = docComment?.replace(Regex("\\s+"), "")
            tableStatement.append(fieldName).append(" ").append(defaultValue.mType).append(" NOT NULL DEFAULT ").append(defaultValue.defaultValue)
            if (fieldName.startsWith("update") && MySQLDataTypeDefaultValueEnum.isLocalDateTime(canonicalText)) {
                tableStatement.append(" ON UPDATE CURRENT_TIMESTAMP")
            }
            tableStatement.append(" COMMENT ").append("\'").append(docComment).append("\',")
            if (osName.contains("Windows")) {
                tableStatement.append("\r\n")
            }
            if (osName.contains("Linux")) {
                tableStatement.append("\n")
            }
        }
        tableStatement.append("PRIMARY KEY (`id`)");
        if (osName.contains("Windows")) {
            tableStatement.append("\r\n")
        }
        if (osName.contains("Linux")) {
            tableStatement.append("\n")
        }
        tableStatement.append(")").append("ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC ")
        if (null != psiDocComment){
            var tableComment = psiDocComment.text
            tableComment = tableComment?.replace(Regex("\n|\r\n"), "")
            tableComment = tableComment?.replace(Regex("/"), "")
            tableComment = tableComment?.replace(Regex("\\*"), "")
            tableComment = tableComment?.replace(Regex("\\s+"), "")
            tableStatement.append("COMMENT='").append(tableComment).append("'")
        }
        tableStatement.append(";")
        val ddlDialog = GeneratorDDLDialog(tableStatement.toString(),project)
        ddlDialog.show()
    }

    private fun getTableName(psiJavaFile: PsiJavaFile): String {
        val className = getClassName(psiJavaFile)
        if (className != null) {
            return NameHandleUtil.camelCaseToUnderscore(className)
        }
        return ""
    }

    private fun getClassName(psiJavaFile: PsiJavaFile):String? {
        return psiJavaFile.classes[0].name
    }
}